package com.yanqu.road.server.manger.activity.qixi;

import com.yanqu.road.dao.impl.player.UserQixiRelationDaoImpl;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.qixi.UserQixiRelationData;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.activity.qixi.QixiConfig;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.thread.ThreadTaskManger;
import com.yanqu.road.pb.activity.QixiProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.game.service.GameService;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.qixi.QixiModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.qixi.service.*;
import com.yanqu.road.server.manger.activity.qixi.task.QixiReceiveFlowerTask;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.relatives.RelativesMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.sync.message.SyncResponse;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.config.Config;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

public class QixiMgr extends TempMgr {
    private static QixiConfig config;

    private static Map<Long, QixiCacheUserInfo> cacheUserBaseInfoMap = new ConcurrentHashMap<>();

    private static ThreadTaskManger threadTaskManger;

    private static List<Long> allServerList = new ArrayList<>();

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        if (null == threadTaskManger) {
            threadTaskManger = new ThreadTaskManger(1, "QixiMgr");
        }
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    @Override
    public boolean save() {
        removeOverTimeCacheUserInfo();
        return true;
    }

    public static void reloadActivity() {
        getLogger().info("qixi reloadActivity start");
        List<ActivityInfo> openActivityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.QiXiActivity.getValue());
        if (openActivityInfoList.isEmpty()) {
            getLogger().info("no qixi Activity in show time");
            config = null;
            allServerList = new ArrayList<>();
        } else {
            ActivityInfo tempActivityInfo = openActivityInfoList.get(0);
            List<Integer> activityIdList = new ArrayList<>();
            int activityId = tempActivityInfo.getActivityId();
            activityIdList.add(activityId);
            Map<String, ActivityConfig> activityConfigMap = ActivityMgr.getActivityConfigMap(activityId);
            QixiConfig qixiConfig = new QixiConfig(tempActivityInfo, activityConfigMap);
            String nowTimeStr = DateHelper.getCurrentDateTimeString();
            Set<Long> serverIdSet = ActivityBussiness.getAllOpenServerListByActivityType(eActivityType.QiXiActivity.getValue(), nowTimeStr);
            config = qixiConfig;
            allServerList = new ArrayList<>(serverIdSet);
        }

        getLogger().info("qixi reloadActivity end");

        for (GamePlayer player : GamePlayerMgr.getAllOnlinePlayer()) {
            player.getModule(QixiModule.class).initUserData();
            player.getModule(QixiModule.class).syncUserData();
        }
    }

    public static QixiConfig getConfig() {
        return config;
    }

    public static void initService(GameService syncMessageService) {
        syncMessageService.addGameServiceCommand(GameProtocol.S_QIXI_GET_USER_INFO, new QixiGetUserInfoServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_QIXI_SEND_FLOWER, new QixiSendFlowerServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_QIXI_SEARCH_USER, new QixiSearchUserServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_QIXI_GET_MOST_GIFT_TARGET_USER_FROM_GAME, new QixiGetMostGiftTargetUserBackServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_QIXI_SEND_FLOWER_ASYNC_BACK, new QixiSendFlowerAsyncBackServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_QIXI_GET_MOST_GIFT_TARGET_USER, new QixiGetMostGiftTargetUserServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_QIXI_GIFT_BROADCAST_FROM_OTHER, new QixiNewBroadcastFromOtherServiceCmd());
    }

    public static QixiProto.CrossQixiSendFlowerRespMsg.Builder receiveFlower(long sendServerId, long sendUserId, long targetId, int flowerId, int flowerCount, String content) {
        QixiProto.CrossQixiSendFlowerRespMsg.Builder backMsg = QixiProto.CrossQixiSendFlowerRespMsg.newBuilder();
        backMsg.setFlowerId(flowerId);
        backMsg.setFlowerCount(flowerCount);
        backMsg.setTargetUserId(targetId);

        if (getConfig() == null){
            //没活动的服,直接返回结果
            UserInfo userInfo = UserMgr.getUserInfo(targetId);
            if (userInfo == null) {
                backMsg.setRet(GameErrorCode.E_USER_NO_FOUND);
            }else{
                backMsg.setRet(0);
                backMsg.setTargetUserId(targetId);
                backMsg.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId())));
                backMsg.setContent(content);
                backMsg.setSendUserId(sendUserId);
            }
        }else{
            GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(targetId);
            if (onlinePlayer != null) {
                QixiProto.CrossQixiSendFlowerRespMsg.Builder resultMsg = onlinePlayer.getModule(QixiModule.class).receiveFlower(sendUserId, flowerId, flowerCount, content);
                backMsg.setRet(resultMsg.getRet());
                backMsg.setRemainCanReceive(resultMsg.getRemainCanReceive());
                if (resultMsg.getRet() == 0) {
                    backMsg.setTargetUserId(targetId);
                    backMsg.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.parseUserBaseInfo(onlinePlayer.getUserInfo(), GameServer.getInstance().getServerId())));
                    backMsg.setFlowerId(flowerId);
                    backMsg.setFlowerCount(flowerCount);
                    backMsg.setContent(content);
                    backMsg.setSendUserId(sendUserId);
                }
            } else {//离线玩家处理
                UserInfo userInfo = UserMgr.getUserInfo(targetId);
                if (userInfo != null) {
                    threadTaskManger.addTask(0, new QixiReceiveFlowerTask(sendServerId, sendUserId, targetId, flowerId, flowerCount, content));
                    return null;
                }else{
                    return backMsg.setRet(GameErrorCode.E_USER_NO_FOUND);
                }
            }
        }

        return backMsg;
    }

    public static QixiProto.QixiSearchUserRespMsg.Builder searchUser(long serverId, long userAliasId) {
        QixiProto.QixiSearchUserRespMsg.Builder respMsg = QixiProto.QixiSearchUserRespMsg.newBuilder();
        respMsg.setRet(0);

        if (QixiMgr.getConfig() == null || !ActivityMgr.activityInTime(QixiMgr.getConfig().getActivityInfo())) {
            return respMsg.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
        }

        UserInfo userInfo = UserMgr.getUserInfoByAliasId(userAliasId);
        if (userInfo == null) {
            return respMsg.setRet(GameErrorCode.E_USER_NO_FOUND);
        }

        UserBaseInfo userBaseInfo = UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId());
        QixiProto.QixiRelationTemp.Builder relationTemp = QixiProto.QixiRelationTemp.newBuilder();
        relationTemp.setTargetUserId(userInfo.getUserId());
        relationTemp.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        relationTemp.setSendFlowerCount(0);
        relationTemp.setGetFlowerCount(0);

        respMsg.setUserRelation(relationTemp);

        return respMsg;
    }

    public static long getGiftMostUserIdByRelationMap(Map<Long, UserQixiRelationData> dataMap) {
        int maxCount = 0;
        long maxCountUserId = 0;
        long compareTime = 0;
        for (UserQixiRelationData relationData : dataMap.values()) {
            if (maxCountUserId == 0) {
                maxCount = relationData.getGetFlowerCount();
                maxCountUserId = relationData.getTargetUserId();
                compareTime = relationData.getGetTime();
            }

            if (relationData.getGetFlowerCount() == maxCount && relationData.getGetTime() > compareTime) {
                maxCount = relationData.getGetFlowerCount();
                maxCountUserId = relationData.getTargetUserId();
                compareTime = relationData.getGetTime();
            }

            if (relationData.getGetFlowerCount() > maxCount) {
                maxCount = relationData.getGetFlowerCount();
                maxCountUserId = relationData.getTargetUserId();
                compareTime = relationData.getGetTime();
            }
        }

        return maxCountUserId;
    }

    public static void getGiftTargetMostUserInfo(long fromServerId, long fromUserId, long targetUserId) {

        long targetServerId = RelativesMgr.getUserServerId(targetUserId);
        CrossUnionMember unionMember = CrossUnionMgr.getUnionMember(targetUserId);
        if (unionMember != null) {
            targetServerId = unionMember.getServerId();
        } else {
            UserInfo userInfo = UserMgr.getUserInfo(targetUserId);
            if (userInfo != null) {
                targetServerId = userInfo.getOriginalServerId();
            }
        }

        if (targetServerId == GameServer.getInstance().getServerId()){
            GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(targetUserId);
            long giftMostUserId = 0;
            if (onlinePlayer != null) {
                giftMostUserId = onlinePlayer.getModule(QixiModule.class).getGiftMostUserId();
            }else{
                Map<Long, UserQixiRelationData> userQixiRelationDataMap = new UserQixiRelationDaoImpl().getUserQixiRelationDataMap(getConfig().getActivityId(), targetUserId);
                giftMostUserId = getGiftMostUserIdByRelationMap(userQixiRelationDataMap);
            }

            getUserInfoByMostGiftUserId(fromServerId, fromUserId, targetUserId, giftMostUserId);
        }else{//去其他服取
            QixiProto.QixiGetMostGiftTargetUserReqMsg.Builder reqMsg = QixiProto.QixiGetMostGiftTargetUserReqMsg.newBuilder();
            reqMsg.setActivityId(QixiMgr.getConfig().getActivityId());
            reqMsg.setTargetUserId(targetUserId);

            QixiProto.CrossQixiGetMostGiftTargetUserRespMsg.Builder resp = QixiProto.CrossQixiGetMostGiftTargetUserRespMsg.newBuilder();

            CompletableFuture<SyncResponse> future = GamePlayerMgr.sendToGameServer(targetServerId, GameProtocol.S_QIXI_GET_MOST_GIFT_TARGET_USER, fromUserId, reqMsg, resp);
            future.thenAccept((SyncResponse syncResponse) -> {
                if (syncResponse.getErrorCode() != 0) {
                    getLogger().error("getGiftTargetMostUserInfo error, errorCode:{}", syncResponse.getErrorCode());
                    return;
                }

                getUserInfoByMostGiftUserId(fromServerId, fromUserId, targetUserId, resp.getUserId());
            });
        }
    }

    public static void getUserInfoByMostGiftUserId(long fromServerId, long fromUserId, long targetUserId, long mostGiftUserId){
        UserBaseInfo userBaseInfo = null;

        CrossUnionMember unionMember = CrossUnionMgr.getUnionMember(mostGiftUserId);
        if (unionMember != null) {
            userBaseInfo = unionMember.getUserBaseInfo();
        } else {
            UserInfo userInfo = UserMgr.getUserInfo(mostGiftUserId);
            if (userInfo != null) {
                userBaseInfo = UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId());
            }
        }

        if (userBaseInfo == null){
            long targetServerId = RelativesMgr.getUserServerId(mostGiftUserId);

            QixiProto.QixiGetUserInfoReqMsg.Builder reqMsg = QixiProto.QixiGetUserInfoReqMsg.newBuilder();
            reqMsg.setActivityId(QixiMgr.getConfig().getActivityId());
            reqMsg.addTargetUserId(mostGiftUserId);
            reqMsg.setReqProtocolType(GameProtocol.S_QIXI_GET_MOST_GIFT_TARGET_USER);

            QixiProto.QixiGetUserInfoRespMsg.Builder resp = QixiProto.QixiGetUserInfoRespMsg.newBuilder();

            CompletableFuture<SyncResponse> future = GamePlayerMgr.sendToGameServer(targetServerId, GameProtocol.S_QIXI_GET_USER_INFO, fromUserId, reqMsg, resp);
            future.thenAccept((SyncResponse syncResponse) -> {
                QixiProto.QixiGetMostGiftTargetUserRespMsg.Builder resultMsg = QixiProto.QixiGetMostGiftTargetUserRespMsg.newBuilder();
                resultMsg.setRet(0);
                if (syncResponse.getErrorCode() != 0) {
                    resultMsg.setRet(syncResponse.getErrorCode());
                }

                if (resp.getReqProtocolType() != GameProtocol.S_QIXI_GET_MOST_GIFT_TARGET_USER) {
                    return;
                }

                if (resultMsg.getRet() == 0) {
                    resultMsg.setActivityId(QixiMgr.getConfig().getActivityId());
                    for (QixiProto.QixiRelationTemp temp : resp.getRelationListList()) {
                        resultMsg.setUserBaseInfo(temp.getUserBaseInfo());
                        resultMsg.setTargetUserId(targetUserId);
                        resultMsg.setMostGiftUserId(temp.getTargetUserId());
                        break;
                    }
                }

                sendGiftTargetMostUserInfo(fromServerId, fromUserId, resultMsg);

            });
        } else {
            QixiProto.QixiGetMostGiftTargetUserRespMsg.Builder resultMsg = QixiProto.QixiGetMostGiftTargetUserRespMsg.newBuilder();
            resultMsg.setRet(0);
            resultMsg.setActivityId(QixiMgr.getConfig().getActivityId());
            resultMsg.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            resultMsg.setTargetUserId(targetUserId);
            resultMsg.setMostGiftUserId(mostGiftUserId);
            sendGiftTargetMostUserInfo(fromServerId, fromUserId, resultMsg);
        }

    }

    public static void sendGiftTargetMostUserInfo(long fromServerId, long fromUserId, QixiProto.QixiGetMostGiftTargetUserRespMsg.Builder resultMsg) {
        if (fromServerId == GameServer.getInstance().getServerId()) {
            GamePlayerMgr.sendPacket(fromUserId, YanQuMessageUtils.buildMessage(ClientProtocol.U_QIXI_GET_MOST_GIFT_TARGET_USER, resultMsg));
        } else {
            GamePlayerMgr.sendToGameServer(fromServerId, GameProtocol.S_QIXI_GET_MOST_GIFT_TARGET_USER_FROM_GAME, fromUserId, resultMsg, null);
        }
    }

    public static void addCacheUserInfo(long userId, PlayerProto.PlayerBaseTempMsg userBaseTemp) {
        QixiCacheUserInfo qixiCacheUserInfo = cacheUserBaseInfoMap.get(userId);
        if (qixiCacheUserInfo == null) {
            synchronized (cacheUserBaseInfoMap) {
                qixiCacheUserInfo = cacheUserBaseInfoMap.get(userId);
                if (qixiCacheUserInfo == null) {
                    QixiCacheUserInfo newQixiCacheUserInfo = new QixiCacheUserInfo(userId, DateHelper.getCurrentTime(), userBaseTemp);
                    cacheUserBaseInfoMap.put(userId, newQixiCacheUserInfo);
                }
            }
        } else {
            qixiCacheUserInfo.setUserId(userId);
            qixiCacheUserInfo.setCacheTime(DateHelper.getCurrentTime());
            qixiCacheUserInfo.setPlayerBaseTempMsg(userBaseTemp);
        }
    }

    public static PlayerProto.PlayerBaseTempMsg getCacheUserInfo(long userId) {
        QixiCacheUserInfo qixiCacheUserInfo = cacheUserBaseInfoMap.get(userId);
        if (qixiCacheUserInfo == null) {
            return null;
        }
        return qixiCacheUserInfo.getPlayerBaseTempMsg();
    }

    /**
     * 超过1个小时的玩家信息清掉等待重新拉。
     */
    public static void removeOverTimeCacheUserInfo() {
        long currentTime = DateHelper.getCurrentTime();
        synchronized (cacheUserBaseInfoMap) {
            for (Long userId : cacheUserBaseInfoMap.keySet()) {
                QixiCacheUserInfo qixiCacheUserInfo = cacheUserBaseInfoMap.get(userId);
                if (qixiCacheUserInfo == null) {
                    continue;
                }
                if (currentTime - qixiCacheUserInfo.getCacheTime() > 60 * DateHelper.MINUTE_MILLIONS) {
                    cacheUserBaseInfoMap.remove(userId);
                }
            }
        }
    }

    public static Property getGiftReward(GoodsInfo goodsInfo, int count) {
        ////物品类别161 花满七夕道具  参数列表：送花数|戒指id|戒指数量|每日赠送上限|是否广播,   赠送上限-1表示无限制，0表示不广播，1广播
        int rewardId = goodsInfo.getParamList().get(1).intValue();
        BigInteger rewardNum = goodsInfo.getParamList().get(2).multiply(BigInteger.valueOf(count));
        Property property = new Property(rewardId, rewardNum);
        return property;
    }

    public static QixiProto.QixiRelationTopGetListRespMsg.Builder getRelationList(long targetUserId, long targetServerId, int activityId) {
        long serverId = ConfigHelper.getLong("serverId");

        QixiProto.QixiRelationTopGetListRespMsg.Builder respMsg = QixiProto.QixiRelationTopGetListRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setActivityId(QixiMgr.getConfig().getActivityId());
        respMsg.setServerId(targetServerId);
        respMsg.setTargetUserId(targetUserId);

        Map<Long, UserQixiRelationData> userRelationMap;
        GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(targetUserId);
        if(onlinePlayer == null){
            userRelationMap = new UserQixiRelationDaoImpl().getUserQixiRelationDataMap(QixiMgr.getConfig().getActivityId(), targetUserId);
        }else {
            userRelationMap = onlinePlayer.getModule(QixiModule.class).getUserRelationMap();
        }

        buildRelation(serverId, respMsg, userRelationMap);

        return respMsg;
    }

    public static void buildRelation(long serverId, QixiProto.QixiRelationTopGetListRespMsg.Builder respMsg, Map<Long, UserQixiRelationData> userRelationMap) {
        List<UserQixiRelationData> relationDataList = new ArrayList<>(userRelationMap.values());
        relationDataList.sort((o1, o2) -> {
            int compare = Integer.compare(o2.getGetFlowerCount(), o1.getGetFlowerCount());
            if (compare == 0) {
                compare = Long.compare(o1.getSendTime(), o2.getSendTime());
            }
            return compare;
        });

        for (int i = 0; i < relationDataList.size() && i < 10; i++) {
            UserQixiRelationData qixiRelationData = relationDataList.get(i);
            if(qixiRelationData.getGetFlowerCount() == 0){
                continue;
            }
            long userId = qixiRelationData.getTargetUserId();
            long userServerId = RelativesMgr.getUserServerId(userId);
            if(Config.isDebug()){
                long id = RelativesMgr.getUserServerId(qixiRelationData.getUserId());
                if(userServerId == id){
                    userServerId = serverId;
                }
            }

            UserBaseInfo userBaseInfo;
            if(userServerId == serverId){
                userBaseInfo = UserMgr.getUserBaseInfo(userId, serverId);
            }else {
                //本服没有去商会找一下
                CrossUnionMember unionMember = CrossUnionMgr.getUnionMember(userId);
                if (unionMember != null) {
                    userBaseInfo = unionMember.getUserBaseInfo();
                }else {
                    //找下亲家
                    userBaseInfo = RelativesMgr.getCacheOtherServerUserMap().get(userId);
                }
            }
            PlayerProto.PlayerBaseTempMsg cacheUserInfo = null;
            if(userBaseInfo == null){

                cacheUserInfo = QixiMgr.getCacheUserInfo(userId);

                if(cacheUserInfo == null) {
                    //拉取玩家数据

                    QixiProto.QixiGetUserInfoReqMsg.Builder reqMsg = QixiProto.QixiGetUserInfoReqMsg.newBuilder();
                    reqMsg.setActivityId(QixiMgr.getConfig().getActivityId());
                    reqMsg.addTargetUserId(userId);
                    reqMsg.setReqProtocolType(GameProtocol.S_QIXI_GET_RELATION_TOP_GET_LIST);

                    QixiProto.QixiGetUserInfoRespMsg.Builder resp = QixiProto.QixiGetUserInfoRespMsg.newBuilder();

                    CompletableFuture<SyncResponse> future = GamePlayerMgr.sendToGameServer(userServerId, GameProtocol.S_QIXI_GET_USER_INFO, qixiRelationData.getUserId(), reqMsg, resp);
                    future.thenAccept((SyncResponse syncResponse) -> {

                        if (syncResponse.getErrorCode() != 0) {
                            return;
                        }
                        if (resp.getReqProtocolType() != GameProtocol.S_QIXI_GET_RELATION_TOP_GET_LIST) {
                            return;
                        }

                        for (QixiProto.QixiRelationTemp temp : resp.getRelationListList()) {
                            QixiMgr.addCacheUserInfo(temp.getTargetUserId(), temp.getUserBaseInfo());
                        }

                    });

                    continue;
                }
            }

            QixiProto.QixiRelationTemp.Builder relationTemp = QixiProto.QixiRelationTemp.newBuilder();
            relationTemp.setTargetUserId(qixiRelationData.getTargetUserId());
            relationTemp.setGetFlowerCount(qixiRelationData.getGetFlowerCount());
            relationTemp.setSendFlowerCount(qixiRelationData.getSendFlowerCount());

            if(userBaseInfo != null) {
                relationTemp.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            }
            if(cacheUserInfo != null){
                relationTemp.setUserBaseInfo(cacheUserInfo);
            }
            respMsg.addRelationList(relationTemp);

        }
    }

    public static QixiProto.QixiAllOpenServerListSyncMsg.Builder getAllOpenServerListMsg() {
        QixiProto.QixiAllOpenServerListSyncMsg.Builder builder = QixiProto.QixiAllOpenServerListSyncMsg.newBuilder();
        builder.addAllServerId(allServerList);
        return builder;
    }
}
